﻿using System.Linq;
using System.Reflection;
using System.Text;
using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using SharedObjects;

namespace System
{
	public static class Utils
	{
		public static bool TryAttachObject(this IObjectContainer db, ref EntityBase b)
		{
			ulong id = b.Id;
			EntityBase objInDb = (from EntityBase e in db where e.Id == id select e).FirstOrDefault();
			if (objInDb == null)
				return false;
			b = objInDb;
			return true;
		}

		public static bool CanDeleteObject(this IObjectContainer db, EntityBase objToDelete)
		{
			Type objType = objToDelete.GetType();
			var attributes = objType.GetCustomAttributes(typeof(ReferencedByAttribute), true).OfType<ReferencedByAttribute>();
			foreach (ReferencedByAttribute a in attributes)
			{
				//get type that references objToDelete
				Type lookupType = a.ByType;
				//Get all objects of this type from db
				var lookup = (from EntityBase b in db where b.GetType() == lookupType select b);
				//iterate thru objects. Foreach referencing object
				foreach (EntityBase b in lookup)
				{
					//foreach property of that object
					foreach (PropertyInfo pi in b.GetType().GetProperties())
					{
						//if that property is of the same type as objToDelete
						if (pi.PropertyType == objToDelete.GetType())
						{
							//obtain property value of this object
							EntityBase check = pi.GetValue(b, null) as EntityBase;

							//if check object has same ID as objToDelete
							if (check != null)
								if (check.Id == objToDelete.Id)
									return false;
						}
					}
				}
			}
			return true;
		}

		public static void DeleteEntity(this IObjectContainer db, EntityBase sourceObject)
		{
			if(sourceObject == null)
				return;
			EntityBase objInDb = (from EntityBase b in db where b.Id == sourceObject.Id select b).FirstOrDefault();
			if(objInDb == null)
				return;
			db.Delete(objInDb);
		}

		public static string ToHexChars(this string s)
		{
			return BitConverter.ToString(Encoding.UTF8.GetBytes(s));
		}
	}
}